package com.nuoniu.sibanyun.service.so.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.production.VProductionWorkDetail;
import com.nuoniu.sibanyun.entity.so.VSaleOrderMain;
import com.nuoniu.sibanyun.entity.so.VSaleQuotationDetail;
import com.nuoniu.sibanyun.entity.so.VSaleQuotationMain;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.mapper.so.VSaleQuotationMainMapper;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsService;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.service.so.IVSaleOrderMainService;
import com.nuoniu.sibanyun.service.so.IVSaleQuotationDetailService;
import com.nuoniu.sibanyun.service.so.IVSaleQuotationMainService;
import com.nuoniu.sibanyun.service.utils.ErpUtils;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 销售报价单主表 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2020-12-07
 */
@Service
@Transactional
public class VSaleQuotationMainServiceImpl extends ServiceImpl<VSaleQuotationMainMapper, VSaleQuotationMain> implements IVSaleQuotationMainService {

    @Autowired
    private IVSaleQuotationDetailService saleQuotationDetailService;
    @Autowired
    private IVSaleOrderMainService saleOrderMainService;
    @Autowired
    private IErpAccountService accountService;
    @Autowired
    private IErpAccountService erpAccountService;
    @Autowired
    private ErpNumberSetMapper numberSetMapper;
    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private ICrmGoodsService crmGoodsService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveOrder(VSaleQuotationMain saleQuotationMain) {
        UserInfo userInfo = UserThreadLocal.get();
        Long mainId = saleQuotationMain.getId();
        List<VSaleQuotationDetail> orderDetailList = saleQuotationMain.getOrderDetailList();
        VSaleQuotationMain oldVSaleQuotationMain = null;
        if(mainId == null) {
            String code = getCode();
            if(code == null) {
                throw new NuoNiuException("单据编号已上限");
            }
            //校验详情（详情不能有ID）
            boolean isHaveId = orderDetailList.stream().anyMatch(f -> null != f.getId());
            if(isHaveId)throw new NuoNiuException("单据明细错误：不能新增已经存在的明细记录");
            saleQuotationMain.setVoucherState(-1);
            saleQuotationMain.setVoucherCode(code);
            saleQuotationMain.setAccountId(accountService.getCurrentAccountId());
            saleQuotationMain.setCompanyId(userInfo.getCompanyId());
            saleQuotationMain.setCreateUserName(userInfo.getRealName());
            saleQuotationMain.setCreateUserId(userInfo.getUserId());
            saleQuotationMain.setCreateDate(LocalDateTime.now());
        }else {
            //校验详情（详情不能有其他单据的明细ID）
            boolean isHaveErrorId = orderDetailList.stream().anyMatch(f -> null != f.getOrderId() && !mainId.toString().equals(f.getOrderId().toString()));
            if(isHaveErrorId)throw new NuoNiuException("单据明细错误：不能修改其他单据的明细记录");
            oldVSaleQuotationMain = getById(mainId);
            Integer voucherState = oldVSaleQuotationMain.getVoucherState();
            if(voucherState != null && voucherState > -1) {
                throw new NuoNiuException("已提交,不能修改");
            }
            saleQuotationMain.setAccountId(oldVSaleQuotationMain.getAccountId());
            saleQuotationMain.setUpdateDate(LocalDateTime.now());
            saleQuotationMain.setUpdateUserId(userInfo.getUserId());
            saleQuotationMain.setUpdateUserName(userInfo.getRealName());
        }
        saleQuotationMain.setCumExecuteQuantity(null);
        // 校验 明细数量
        boolean isOk = saleQuotationMain.getOrderDetailList().stream().anyMatch(f -> null == f.getBaseQuantity() || !(f.getBaseQuantity().compareTo(BigDecimal.ZERO) > 0));
        if(isOk)throw new NuoNiuException("明细数量必须大于0");
        //计算 明细物料 总数
        BigDecimal totalQuantity =  saleQuotationMain.getOrderDetailList().stream().map(VSaleQuotationDetail::getBaseQuantity).reduce(BigDecimal.ZERO,BigDecimal::add);
        saleQuotationMain.setTotalQuantity(totalQuantity.abs());

        //保存主单据
        Boolean result = this.saveOrUpdate(saleQuotationMain);
        if(result) {
            List<Long> detailIds = new ArrayList<>();
            orderDetailList.forEach(p -> {
                if(p.getId() != null) {
                    detailIds.add(p.getId());
                }
                p.setOrderId(saleQuotationMain.getId().intValue());
                p.setCompanyId(userInfo.getCompanyId());
                p.setAccountId(saleQuotationMain.getAccountId());
            });

            //删除明细
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_id", mainId);
            if(detailIds != null && detailIds.size() > 0) {
                wrapper.notIn("id", detailIds);
                saleQuotationDetailService.remove(wrapper);
            }else {
                saleQuotationDetailService.remove(wrapper);
            }
            //保存单据明细表
            saleQuotationDetailService.saveOrUpdateBatch(orderDetailList);
        }
    }

    @Override
    public String getCode() {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        ErpNumberSet numberSet = numberSetMapper.getByCode("SaleQuotation", userInfo.getCompanyId(), currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getCode(userInfo.getCompanyId(), dateStr);
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteById(Long id) {
        VSaleQuotationMain quotationMain = getById(id);
        Integer voucherState = quotationMain.getVoucherState();
        if(null != voucherState && voucherState > -1){
            throw new NuoNiuException("已提交,不能删除");
        }
        List<VSaleOrderMain> saleOrderMains = saleOrderMainService.getBySourceId(id);
        /**************  修改权限 *******************/
        if(!crmGoodsService.isHaveOperationRight(quotationMain.getCreateUserId().longValue())){
            throw new NuoNiuException("你没有权限操作该记录");
        }

        if(saleOrderMains.size() > 0) {
            throw new NuoNiuException("已生成销售单,不能删除");
        }
        //删除 主表
        removeById(id);
        //删除明细表
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_id", id);
        saleQuotationDetailService.remove(wrapper);

    }

    @Override
    public void submit(Long id, Integer status) {
        if(null == id || null == status || (null != status && (status > 0 || status < -1 )))throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VSaleQuotationMain saleQuotationMain = this.getById(id);
        if( null == saleQuotationMain)throw new NuoNiuException("记录不存在");
        //校验状态
        Integer voucherState = saleQuotationMain.getVoucherState();
        /**  统一校验 提交状态 */
        ErpUtils.checkSubmitStatus(voucherState,status);
        //提交
        saleQuotationMain.setVoucherState(status);
        saleQuotationMain.setSubmitDate(LocalDateTime.now());
        saleQuotationMain.setSubmitUserId(userInfo.getUserId());
        saleQuotationMain.setSubmitUserName(userInfo.getRealName());
        this.updateById(saleQuotationMain);
    }

    @Override
    public void examine(Long id, Integer status) {
        if(null == id || null == status ||  (status > 1 || status < 0) )throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VSaleQuotationMain quotationMain = this.getById(id);
        if(quotationMain == null) throw  new NuoNiuException("没有查询到相关记录");
        Integer voucherState = quotationMain.getVoucherState();
        BigDecimal cumExecuteQuantity = quotationMain.getCumExecuteQuantity();
        /** 统一校验 审核状态*/
        ErpUtils.checkExamineStatus(voucherState,status,cumExecuteQuantity);
        quotationMain.setVoucherState(status);
        quotationMain.setReviewerDate(LocalDateTime.now());
        quotationMain.setReviewerUserId(userInfo.getUserId());
        quotationMain.setReviewerUserName(userInfo.getRealName());
        this.updateById(quotationMain);
    }
}
